package com.dfe.backend.controller;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.dfe.backend.common.constant.BaseConstant;
import com.dfe.backend.common.util.ZipUtil;
import com.dfe.backend.common.validation.ValidGroup;
import com.dfe.backend.data.RtnData;
import com.dfe.backend.dto.AnalyseFileDTO;
import com.dfe.backend.entity.DfeFile;
import com.dfe.backend.service.DfeFileService;
import lombok.AccessLevel;
import lombok.RequiredArgsConstructor;
import lombok.experimental.FieldDefaults;
import lombok.experimental.NonFinal;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.sql.Timestamp;
import java.util.Objects;

/**
 * 【描述】：文件控制器
 *
 * @author LiChang
 * @since 2025-8-1 9:00
 */
@RestController
@RequestMapping("/file")
@RequiredArgsConstructor
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
public class FileController extends BaseController {

    DfeFileService dfeFileService;

    @NonFinal
    @Value("${config.filePath.scd}")
    String scdPath;

    /**
     * 【描述】: 文件分析
     *
     * @param fileDTO fileDTO
     * @return {@link RtnData}
     * @author LiChang
     * @since 2025-8-4 8:38
     */
    @PostMapping("/analyseFile")
    public RtnData analyseFile(@RequestBody @Validated({ValidGroup.Update.class}) AnalyseFileDTO fileDTO, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return RtnData.fail(null, BaseConstant.MISS_PARAM, "参数缺失，文件分析失败！");
        }
        try {
            // 文件分析
            String fileType = fileDTO.getFileType();
            String filePath = fileDTO.getFilePath();
            if ("scd".equals(fileType)) {
                filePath = scdPath;
            }
            dfeFileService.analyseFile(filePath, fileType);
            return RtnData.ok("分析文件已开始！");
        } catch (Exception e) {
            return RtnData.fail(null, BaseConstant.SYSTEM_ERROR, "分析文件失败！");
        }
    }


    /**
     * 【描述】: Zip文件上传
     *
     * @param file file
     * @return {@link RtnData}
     * @author LiChang
     * @since 2025-8-4 8:38
     */
    @PostMapping("/uploadZipFile")
    public RtnData uploadZipFile(@RequestPart("file") MultipartFile file) {
        try {
            if (file == null) {
                return RtnData.fail(null, BaseConstant.MISS_PARAM, "未选择文件，请选择要上传的文件！");
            }
            // 判断导入文件是否为.zip
            boolean isZipFile = Objects.requireNonNull(file.getOriginalFilename()).toLowerCase().endsWith(".zip");
            if (isZipFile) {
                // 获取zip文件扩展名
                String zipFileExtension = ZipUtil.getValidZipExtensionByInputStream(file);
                if (StrUtil.isEmpty(zipFileExtension)) {
                    return RtnData.fail(null, BaseConstant.MISS_PARAM, "导入文件失败，上传文件不符合要求！");
                }
                boolean existZipFile = dfeFileService.exists(new QueryWrapper<DfeFile>().eq("file_type", zipFileExtension));
                // 判断文件名是否重复
                boolean existFlag = dfeFileService.exists(new QueryWrapper<DfeFile>().eq("file_name", file.getOriginalFilename()));
                if (existZipFile) {
                    return RtnData.fail(null, BaseConstant.MISS_PARAM, "新增文件信息失败，已存在" + zipFileExtension + "文件！");
                } else if (existFlag) {
                    // 提示前端，覆盖的话，调用更新接口，新增的话，修改文件名
                    return RtnData.fail(null, BaseConstant.MISS_PARAM, "新增文件信息失败，文件名重复！");
                } else {
                    //获取文件路径
                    String filePath = dfeFileService.uploadZipFile(file, zipFileExtension);
                    DfeFile dfeFile = new DfeFile();
                    dfeFile.setFileName(file.getOriginalFilename());
                    dfeFile.setFileUrl(filePath);
                    dfeFile.setFileType(zipFileExtension);
                    return RtnData.ok(dfeFile);
                }
            } else {
                return RtnData.fail(null, BaseConstant.MISS_PARAM, "上传文件格式错误，请上传zip文件！");
            }
        } catch (Exception e) {
            return RtnData.fail(null, BaseConstant.SYSTEM_ERROR, "导入文件失败！");
        }
    }

    /**
     * 【描述】: 文件保存
     *
     * @param dfeFile       dfeFile
     * @param bindingResult bindingResult
     * @return {@link RtnData}
     * @author LiChang
     * @since 2025-8-7 14:43
     */
    @PostMapping("/saveFile")
    public RtnData saveFile(@RequestBody @Validated({ValidGroup.Insert.class}) DfeFile dfeFile, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return RtnData.fail(null, BaseConstant.MISS_PARAM, "请上传文件!");
        }
        if (dfeFile != null) {
            // 获取文件类型
            String type = dfeFile.getFileType();
            if (StrUtil.isNotEmpty(type) && ("scd".equalsIgnoreCase(type) || "spd".equalsIgnoreCase(type))) {
                boolean isExist = dfeFileService.exists(new QueryWrapper<DfeFile>().eq("file_type", type));
                if (isExist) {
                    return RtnData.fail("已存在SCD/SPD记录,请先将原记录删除后再进行添加！");
                }
                if (!dfeFile.getFileUrl().endsWith(type)) {
                    return RtnData.fail("文件路径与类型不匹配！");
                }
            }
            dfeFile.setCreateTime(new Timestamp(System.currentTimeMillis()));
            boolean flag = dfeFileService.save(dfeFile);
            if (flag) {
                // 文件保存成功后，则自动进行分析
                dfeFileService.analyseFile(dfeFile.getFileUrl(), dfeFile.getFileType());
                return RtnData.ok("文件保存成功！");
            }
        }
        return RtnData.fail(null, BaseConstant.INSERT_ERROR, "文件保存失败！");
    }


    /**
     * 【描述】: 删除文件
     *
     * @param dfeFile       dfeFile
     * @param bindingResult bindingResult
     * @return {@link RtnData}
     * @author LiChang
     * @since 2025-8-8 14:17
     */
    @PostMapping("/deleteFile")
    public RtnData deleteFile(@RequestBody @Validated({ValidGroup.Delete.class}) DfeFile dfeFile, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return RtnData.fail(null, BaseConstant.MISS_PARAM, "参数缺失，删除失败！");
        }
        boolean deleteFlag = dfeFileService.deleteFile(dfeFile.getId());
        if (deleteFlag) {
            return RtnData.ok("文件删除成功！");
        } else {
            return RtnData.fail("文件不存在，删除失败！");
        }
    }

}
